/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package dawnland02.model.action;

import dawnland02.model.entity.attribute.PhysicalAttribute;

/**
 * effect of an attribute:
 *  if direct proportional: MAX(MIN(1+(Value-Req)*PointEffect, MaxEffect), MinEffect)
 *  if indirect proportioanl: MAX(MIN(1+(Req-Value)*PointEffect, MaxEffect), MinEffect)
 * @author Petru Obreja (obrejap@yahoo.com)
 */
public class ActionAttribute {
    private final PhysicalAttribute physicalAttribute;
    private final Double physicalAttributeRequirement;
    private final boolean isThePhysicalAttributeEffectDirectProportional; //true, if an increase of the physicalAttribute corresponds to a gain of the effect
    private final Double effectForOnePointOfPhysicalAttribute;
    private final Double physicalAttributeValueForMinimumEffect;
    private final Double physicalAttributeValueForMaximumEffect;

    public ActionAttribute(PhysicalAttribute physicalAttribute, Double physicalAttributeRequirement, boolean isThePhysicalAttributeEffectDirectProportional, Double effectForOnePointOfPhysicalAttribute, Double physicalAttributeValueForMinimumEffect, Double physicalAttributeValueForMaximumEffect) {
        this.physicalAttribute = physicalAttribute;
        this.physicalAttributeRequirement = physicalAttributeRequirement;
        this.isThePhysicalAttributeEffectDirectProportional = isThePhysicalAttributeEffectDirectProportional;
        this.effectForOnePointOfPhysicalAttribute = effectForOnePointOfPhysicalAttribute;
        this.physicalAttributeValueForMinimumEffect = physicalAttributeValueForMinimumEffect;
        this.physicalAttributeValueForMaximumEffect = physicalAttributeValueForMaximumEffect;
    }

    public PhysicalAttribute getPhysicalAttribute() {
        return physicalAttribute;
    }

    public Double getPhysicalAttributeRequirement() {
        return physicalAttributeRequirement;
    }

    public boolean isIsThePhysicalAttributeEffectDirectProportional() {
        return isThePhysicalAttributeEffectDirectProportional;
    }

    public Double getEffectForOnePointOfPhysicalAttribute() {
        return effectForOnePointOfPhysicalAttribute;
    }

    public Double getPhysicalAttributeValueForMaximumEffect() {
        return physicalAttributeValueForMaximumEffect;
    }

    public Double getPhysicalAttributeValueForMinimumEffect() {
        return physicalAttributeValueForMinimumEffect;
    }

    public Double getEffect(Double attributeValue){
        /* if direct proportional: MAX(MIN(1+(Value-Req)*PointEffect, MaxEffect), MinEffect)
           if indirect proportioanl: MAX(MIN(1+(Req-Value)*PointEffect, MaxEffect), MinEffect)*/
        return Math.max(Math.min(getBasicEffect(attributeValue), getMaximumEffect()), getMinimumEffect());
    }

    public Double getMinimumEffect(){
        return getBasicEffect(getPhysicalAttributeValueForMinimumEffect());
    }

    public Double getMaximumEffect(){
        return getBasicEffect(getPhysicalAttributeValueForMaximumEffect());
    }

    private Double getBasicEffect(Double attributeValue){
        // 1+(Value-Req)*PointEffect;
        if(isThePhysicalAttributeEffectDirectProportional){
            return 1.0+(attributeValue-getPhysicalAttributeRequirement())*getEffectForOnePointOfPhysicalAttribute();
        } else {
            return 1.0+(getPhysicalAttributeRequirement() - attributeValue)*getEffectForOnePointOfPhysicalAttribute();
        }
    }

}
